import {
  Scene,
  WebGLRenderer,
  Mesh,
  PlaneGeometry,
  MeshStandardMaterial,
  MeshPhongMaterial,
  DoubleSide,
  GridHelper,
  PerspectiveCamera,
  DirectionalLight,
  AmbientLight,
  AxesHelper,
  EventDispatcher,
  Vector3,
  OrthographicCamera,
  Fog,
  HemisphereLight,
  Color,
  Object3D,
  Box3,
  TextureLoader,
  RepeatWrapping,
  LinearMipmapLinearFilter,
  LinearFilter
} from "three";

import Interaction from "three.interaction/src/interaction/Interaction.js";
import {
  OrbitControls,
} from "three/examples/jsm/controls/OrbitControls.js";

import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import {
  MapControls,
} from "three/examples/jsm/controls/MapControls.js";

const { VITE_FILE_URL } = import.meta.env;
interface ViewerOptions {
  isDebug: boolean;
  hasAxes: boolean;
}

interface GroundOptions {
  size: [number, number];
  grid: boolean;
}

const defaultOptions: ViewerOptions = {
  isDebug: false,
  hasAxes: false,
};

export default class Viewer {
  public container: HTMLElement;
  public scene: Scene;
  public renderer: WebGLRenderer;
  public camera: PerspectiveCamera;
  public options: ViewerOptions;
  public controls: OrbitControls;
  public renderQueue: Array<any> = [];
  public axesHelper: AxesHelper;
  public labelRenderer;
  public cameraModel = 'free';
  constructor(canvas: Canvas, options: ViewerOptions = defaultOptions) {
    this.canvas = canvas
    this._init(this.canvas);
    this._createCamera();
    // this.interaction = new Interaction(this.renderer, this.scene, this.camera);
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.enablePan = false;
    this.controls.enableZoom = false;

    this.setLight();

    this.render();
    this.resize(containerId);
    const { hasAxes } = this.options;
    if (hasAxes) {
      this._createAxes();
    }
  }

  private _init(canvas) {
    if (!canvas) {
      throw new Error("container is required");
    }
    debugger
    // const { clientWidth, clientHeight } = container;
    // 创建场景
    this.scene = new Scene();
    this.scene.background = new Color(0x000000);


    // 创建webgl渲染器
    this.renderer = new WebGLRenderer({
      canvas: canvas,
    });
    // 设置渲染器窗口大小
    // this.renderer.setSize(clientWidth, clientHeight);

    // container.appendChild(this.renderer.domElement);
  }

  private toggleCamera(type) {
    this.scene.add(new DirectionalLight(0xffffff, 1));
    this.scene.add(new AmbientLight(0xffffff, 0.5));
  }

  private _createAxes() {
    this.axesHelper = new AxesHelper(200);
    this.scene.add(this.axesHelper);
  }

  private _createCamera() {
    const { clientWidth, clientHeight } = this.container;
    this.camera = new PerspectiveCamera(
      30,
      clientWidth / clientHeight,
      1,
      100000
    );
    this.camera.position.set(0, 0, 100);
    this.camera.lookAt(0, 0, 0);

    this.renderQueue.push(() => {
      this.renderer.render(this.scene, this.camera);
    });
  }


  removeModel() {
    if (this.model) {
      this.scene.remove(this.model); // 从场景中移除模型


      // this.model.geometry.dispose(); // 释放几何体资源
      // this.model.material.dispose(); // 释放材质资源
    }
  }

  loadModel(modelUrl: string, meshUrl: string) {

    if (!modelUrl || !meshUrl) {
      return
    }
    this.removeModel();

    const textureLoader = new TextureLoader();
    const loader = new OBJLoader();
    textureLoader.load(`${VITE_FILE_URL}/${meshUrl}`, (texture) => {
      loader.load(`${VITE_FILE_URL}/${modelUrl}`, (model) => {

        // 加载纹理

        texture.magFilter = LinearFilter;
        texture.minFilter = LinearFilter;

        // 遍历模型中的每个 Mesh，将纹理应用到材质上
        model.traverse(function (child) {
          if (child.isMesh) {
            child.material.map = texture; // 设置贴图
            child.material.needsUpdate = true; // 更新材质
          }
        });


        // 计算模型的边界框
        const box = new Box3().setFromObject(model);

        // 计算模型的高度
        const height = box.max.z - box.min.z;
        console.log('模型高度:', height);



        model.position.y = height / -2 - height * 0.05;
        model.rotation.x = -Math.PI / 2;
        this.scene.add(model);

        this.model = model;

        // animate();
      });
    });



  }


  resize(containerId) {
    window.onresize = () => {
      this.container = document.getElementById(containerId);
      const { clientWidth, clientHeight } = this.container;
      this.camera.aspect = clientWidth / clientHeight;
      this.camera.updateProjectionMatrix();
      this.renderer.setSize(clientWidth, clientHeight);
    };
  }


  public setLight() {
    //光源设置
    const hemiLight = new HemisphereLight(0xffffff, 0x8d8d8d, 1);
    hemiLight.position.set(0, 20, 0);
    this.scene.add(hemiLight);

    const directionalLight = new DirectionalLight(0xffffff, 1);
    directionalLight.position.set(100, 60, 50);
    this.scene.add(directionalLight);
    const ambient = new AmbientLight(0xffffff, 0.4);
    this.scene.add(ambient);
  }

  private render() {
    this.renderQueue.forEach((render) => render());
    // requestAnimationFrame(this.render.bind(this));
    setInterval(this.render.bind(this), 200)
  }

  add(instance: Object3D) {
    this.scene.add(instance);
    const name = instance.constructor.name;
    this[name] = instance;
  }

}
